/*
 * Group 3, User Interface Programming II (vt11)
 * Pooya | Flora | Monica | Can
 */
package vical.view;

import java.awt.event.ItemEvent;
import java.text.ParseException;
import javax.swing.*;
import com.toedter.calendar.JDateChooser;
import java.awt.*;
import java.awt.event.ItemListener;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import vical.action.AddEntryAction;
import vical.action.DeleteEntryAction;
import vical.controller.EntryController;
import vical.controller.PreferenceController;
import vical.model.Entry;
import vical.model.Internationalization;

/**
 * The panel for displaying, editing a single entry.
 * 
 * @author Can
 * @author Pooya
 * @author Monica
 * @author Flora
 */
public class EntryDialog extends JDialog {

    // components
    private JLabel entryNameLabel;
    private UndoableTextField entrytNameTextArea;
    private JLabel entryDescriptionLabel;
    private UndoableTextArea entryDescriptionTextArea;
    private JLabel categoryLabel;
    private JComboBox categoryComboBox;
    private JLabel priorityLabel;
    private JComboBox priorityComboBox;
    private JLabel endDateLabel;
    private String prioLabels[] = {"Normal", "High"};
    private JDateChooser endDateChooser;
    private JLabel startDateLabel;
    private JDateChooser startDateChooser;
    private JLabel startTimeLabel;
    private JSpinner startTimeSpinner;
    private JLabel endTimeLabel;
    private JSpinner endTimeSpinner;
    private JCheckBox allDayCheckBox;
    private JComboBox specialEventComboBox;
    private JPanel entryNamePanel;
    private JPanel timeDatePanel;
    private JPanel entryDescriptionPanel;
    private JPanel categoryPanel;
    private JPanel priorityPanel;
    private JPanel actionPanel;
    private JButton doneButton;
    private JButton deleteButton;
    //
    private Entry entry;
    private final int defaultWidth = 450;
    private final int defaultHeight = 400;
    private int defaultLableWidth = 90;

    public EntryDialog(Entry entry) {
        this.entry = entry;
        if (this.entry == null) {
            this.entry = new Entry();
        }
        if (PreferenceController.getLocale().equals(new Locale("sv"))) {
            this.defaultLableWidth = 120;
        }
        initComponents();
        updateInterface();
    }

    private EntryDialog() {
    }

    private void initComponents() {

        // entryName Panel
        entryNameLabel = new JLabel(Internationalization.getString("calendar_event_name_label"));
        JPanel entryNameLabelPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        entryNameLabelPanel.setPreferredSize(new Dimension(defaultLableWidth, HEIGHT));
        entryNameLabelPanel.add(entryNameLabel);
        entrytNameTextArea = new UndoableTextField();
        entrytNameTextArea.setToolTipText(Internationalization.getString("tooltip_entrydialog_name"));

        entryNamePanel = new JPanel(new BorderLayout());
        entryNamePanel.add(BorderLayout.WEST, entryNameLabelPanel);
        entryNamePanel.add(BorderLayout.CENTER, entrytNameTextArea);
        entryNamePanel.add(Box.createRigidArea(new Dimension(4, 0)), BorderLayout.EAST);

        // entryDescription Panel
        entryDescriptionLabel = new JLabel(Internationalization.getString("calendar_event_description_label"));
        JPanel entryDescriptionLabelPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        entryDescriptionLabelPanel.setPreferredSize(new Dimension(defaultLableWidth, HEIGHT));
        entryDescriptionLabelPanel.add(entryDescriptionLabel);
        entryDescriptionTextArea = new UndoableTextArea();
        entryDescriptionTextArea.setBorder(BorderFactory.createLineBorder(Color.GRAY));
        entryDescriptionTextArea.setToolTipText(Internationalization.getString("tooltip_entrydialog_description"));

        entryDescriptionPanel = new JPanel(new BorderLayout());
        entryDescriptionPanel.add(entryDescriptionLabelPanel, BorderLayout.WEST);
        entryDescriptionPanel.add(entryDescriptionTextArea, BorderLayout.CENTER);

        // timeDate Panel
        startDateLabel = new JLabel(Internationalization.getString("calendar_start_date_label"));
        JPanel startDateLabelPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        startDateLabelPanel.setPreferredSize(new Dimension(defaultLableWidth, HEIGHT));
        startDateLabelPanel.add(startDateLabel);
        startDateChooser = new JDateChooser();
        startDateChooser.setCalendar(Calendar.getInstance());
        startDateChooser.setToolTipText(Internationalization.getString("tooltip_entrydialog_choose_date"));

        JPanel startDatePanel = new JPanel(new BorderLayout());
        startDatePanel.add(startDateLabelPanel, BorderLayout.WEST);
        startDatePanel.add(startDateChooser, BorderLayout.CENTER);

        startTimeLabel = new JLabel(Internationalization.getString("calendar_start_time_label"));
        startTimeLabel.setPreferredSize(new Dimension(defaultLableWidth, HEIGHT));
        showStartTimeJSpinner();
        startTimeSpinner.setToolTipText(Internationalization.getString("tooltip_entrydialog_start_time"));


        JPanel startTimePanel = new JPanel(new BorderLayout());
        startTimePanel.add(startTimeLabel, BorderLayout.WEST);
        startTimePanel.add(startTimeSpinner, BorderLayout.CENTER);

        JPanel startTimeDatePanel = new JPanel(new GridLayout(1, 2, 5, 2));
        startTimeDatePanel.add(startDatePanel);
        startTimeDatePanel.add(startTimePanel);

        endDateLabel = new JLabel(Internationalization.getString("calendar_end_date_label"));
        JPanel endDateLabelPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        endDateLabelPanel.setPreferredSize(new Dimension(defaultLableWidth, HEIGHT));
        endDateLabelPanel.add(endDateLabel);
        endDateChooser = new JDateChooser();
        endDateChooser.setCalendar(Calendar.getInstance());
        endDateChooser.setToolTipText(Internationalization.getString("tooltip_entrydialog_choose_date"));

        JPanel endDatePanel = new JPanel(new BorderLayout());
        endDatePanel.add(endDateLabelPanel, BorderLayout.WEST);
        endDatePanel.add(endDateChooser, BorderLayout.CENTER);

        endTimeLabel = new JLabel(Internationalization.getString("calendar_end_time_label"));
        endTimeLabel.setPreferredSize(new Dimension(defaultLableWidth, HEIGHT));
        endTimeSpinner = new JSpinner();
        endTimeSpinner.setToolTipText(Internationalization.getString("tooltip_entrydialog_end_time"));
        showEndTimeJSpinner();

        JPanel endTimePanel = new JPanel(new BorderLayout());
        endTimePanel.add(endTimeLabel, BorderLayout.WEST);
        endTimePanel.add(endTimeSpinner, BorderLayout.CENTER);

        JPanel endTimeDatePanel = new JPanel(new GridLayout(1, 2, 5, 2));
        endTimeDatePanel.add(endDatePanel);
        endTimeDatePanel.add(endTimePanel);

        allDayCheckBox = new JCheckBox(Internationalization.getString("calendar_all_day_label"));
        allDayCheckBox.setToolTipText(Internationalization.getString("tooltip_entrydialog_all_day"));
        allDayCheckBox.addItemListener(new ItemListener() {

            public void itemStateChanged(ItemEvent e) {
                boolean visiblity = (e.getStateChange() == ItemEvent.DESELECTED);
                startTimeLabel.setVisible(visiblity);
                endTimeLabel.setVisible(visiblity);
                startTimeSpinner.setVisible(visiblity);
                endTimeSpinner.setVisible(visiblity);
            }
        });

        JPanel allDayPanel = new JPanel(new BorderLayout());
        JPanel emptyLablePanel = new JPanel();
        emptyLablePanel.setPreferredSize(new Dimension(defaultLableWidth, HEIGHT));
        allDayPanel.add(emptyLablePanel, BorderLayout.WEST);
        allDayPanel.add(allDayCheckBox, BorderLayout.CENTER);

        timeDatePanel = new JPanel();
        timeDatePanel.setLayout(new BoxLayout(timeDatePanel, BoxLayout.Y_AXIS));
        timeDatePanel.add(allDayPanel);
        timeDatePanel.add(startTimeDatePanel);
        timeDatePanel.add(endTimeDatePanel);

        // entryTypesPanel
        specialEventComboBox = new JComboBox(Internationalization.getString("SpecialEvents").split(","));
        specialEventComboBox.setToolTipText(Internationalization.getString("tooltip_entrydialog_special_event"));
        JPanel typesLablePanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        typesLablePanel.setPreferredSize(new Dimension(defaultLableWidth, HEIGHT));
        typesLablePanel.add(new JLabel(Internationalization.getString("calendar_special_event_label")));

        JPanel entryTypesPanel = new JPanel(new BorderLayout());
        entryTypesPanel.add(typesLablePanel, BorderLayout.WEST);
        entryTypesPanel.add(specialEventComboBox, BorderLayout.CENTER);
        entryTypesPanel.add(Box.createRigidArea(new Dimension(4, 0)), BorderLayout.EAST);

        // category Panel
        categoryLabel = new JLabel(Internationalization.getString("calendar_category_label"));
        JPanel categoryLabelPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        categoryLabelPanel.setPreferredSize(new Dimension(defaultLableWidth, HEIGHT));
        categoryLabelPanel.add(categoryLabel);

        categoryComboBox = new JComboBox(EntryController.getCategories().toArray());
        categoryComboBox.setEditable(true);
        categoryComboBox.setSelectedIndex(0);
        categoryComboBox.setToolTipText(Internationalization.getString("tooltip_entrydialog_category"));

        categoryPanel = new JPanel(new BorderLayout());
        categoryPanel.add(categoryLabelPanel, BorderLayout.WEST);
        categoryPanel.add(categoryComboBox, BorderLayout.CENTER);
        categoryPanel.add(Box.createRigidArea(new Dimension(4, 0)), BorderLayout.EAST);

        // priority panel
        priorityLabel = new JLabel(Internationalization.getString("calendar_priority_label"));
        JPanel priorityLabelPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        priorityLabelPanel.setPreferredSize(new Dimension(defaultLableWidth, HEIGHT));
        priorityLabelPanel.add(priorityLabel);

        priorityComboBox = new JComboBox(prioLabels);
        priorityComboBox.setSelectedIndex(0);
        priorityComboBox.setToolTipText(Internationalization.getString("tooltip_entrydialog_priority"));

        priorityPanel = new JPanel(new BorderLayout());
        priorityPanel.add(priorityLabelPanel, BorderLayout.WEST);
        priorityPanel.add(priorityComboBox, BorderLayout.CENTER);
        priorityPanel.add(Box.createRigidArea(new Dimension(4, 0)), BorderLayout.EAST);

        // action Panel
        deleteButton = new JButton(getRemoveButtonAction());
        deleteButton.setToolTipText(Internationalization.getString("tooltip_entrydialog_remove"));

        doneButton = new JButton(getDoneButtonAction());
        doneButton.setToolTipText(Internationalization.getString("tooltip_entrydialog_done"));

        actionPanel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        actionPanel.add(deleteButton);
        actionPanel.add(doneButton);
        this.setTitle(Internationalization.getString("entry_dialog_title"));
        JPanel otherInfoPanel = new JPanel();
        otherInfoPanel.setLayout(new BoxLayout(otherInfoPanel, BoxLayout.Y_AXIS));
        otherInfoPanel.add(entryNamePanel);
        otherInfoPanel.add(timeDatePanel);
        otherInfoPanel.add(entryTypesPanel);
        otherInfoPanel.add(categoryPanel);
        otherInfoPanel.add(priorityPanel);

        this.setLayout(new BorderLayout());
        this.add(otherInfoPanel, BorderLayout.NORTH);
        this.add(entryDescriptionPanel, BorderLayout.CENTER);
        this.add(actionPanel, BorderLayout.SOUTH);
        this.add(Box.createRigidArea(new Dimension(4, 0)), BorderLayout.EAST);

        this.getRootPane().setDefaultButton(doneButton);
        this.setSize(defaultWidth, defaultHeight);
        this.setLocationRelativeTo(null);
        this.setModal(true);
    }

    private void showStartTimeJSpinner() {
        Date date = new Date();
        SpinnerDateModel sm = new SpinnerDateModel(date, null, null, Calendar.HOUR_OF_DAY);
        startTimeSpinner = new JSpinner(sm);
        JSpinner.DateEditor de = new JSpinner.DateEditor(startTimeSpinner, "hh:mm");
        startTimeSpinner.setEditor(de);
    }

    private void showEndTimeJSpinner() {
        Date date = new Date();
        SpinnerDateModel sm = new SpinnerDateModel(date, null, null, Calendar.HOUR_OF_DAY + (01));
        endTimeSpinner = new JSpinner(sm);
        JSpinner.DateEditor de = new JSpinner.DateEditor(endTimeSpinner, "hh:mm");
        endTimeSpinner.setEditor(de);
    }

    // update the interface by this.entry
    private void updateInterface() {
        entrytNameTextArea.setText(entry.getName());
        entryDescriptionTextArea.setText(entry.getDescription());
        startDateChooser.setCalendar(entry.getStartTime());
        endDateChooser.setCalendar(entry.getEndTime());
        startTimeSpinner.setValue(entry.getStartTime().getTime());
        endTimeSpinner.setValue(entry.getEndTime().getTime());
        categoryComboBox.setSelectedItem(entry.getCategory());
        priorityComboBox.setSelectedItem(entry.getPriority());
        allDayCheckBox.setSelected(entry.isAllday());
        specialEventComboBox.setSelectedItem(entry.getSpecialEvents());
    }

    private Calendar getStartDateTime() {
        Calendar startDateTime = startDateChooser.getCalendar();
        int startYear = startDateTime.get(Calendar.YEAR);
        int startMonth = startDateTime.get(Calendar.MONTH);
        int startDate = startDateTime.get(Calendar.DATE);
        startDateTime.setTime((Date) startTimeSpinner.getValue());
        startDateTime.set(startYear, startMonth, startDate);
        return startDateTime;
    }

    private Calendar getEndDateTime() {
        Calendar endDateTime = endDateChooser.getCalendar();
        int endYear = endDateTime.get(Calendar.YEAR);
        int endMonth = endDateTime.get(Calendar.MONTH);
        int endDate = endDateTime.get(Calendar.DATE);
        endDateTime.setTime((Date) endTimeSpinner.getValue());
        endDateTime.set(endYear, endMonth, endDate);
        return endDateTime;
    }

    // generate a instance of Entry from interface
    public Entry getEntryFromInterface() {
        try {
            startTimeSpinner.commitEdit();
            endTimeSpinner.commitEdit();
        } catch (ParseException ex) {
            System.out.println("TimeSpinner: " + ex.getLocalizedMessage());
        }
        entry.setName(entrytNameTextArea.getText());
        entry.setAllday(allDayCheckBox.isSelected());
        entry.setStartTime(this.getStartDateTime());
        entry.setEndTime(this.getEndDateTime());
        entry.setCategory(categoryComboBox.getSelectedItem().toString());
        entry.setPriority(priorityComboBox.getSelectedItem().toString());
        entry.setSpecialEvents(specialEventComboBox.getSelectedItem().toString());
        entry.setDescription(entryDescriptionTextArea.getText());
        return entry;
    }

    // TODO: should be abstract method
    protected AbstractAction getDoneButtonAction() {
        return new AddEntryAction(this);
    }

    // TODO: should be abstract method
    protected AbstractAction getRemoveButtonAction() {
        return new DeleteEntryAction(this);
    }

    // for testing
    public static void main(String[] args) {
        if (PreferenceController.loadPreference() != 0) {
            System.exit(-1);
        }
        if (Internationalization.loadLanguage(new java.util.Locale("sv")) != 0) {
            System.exit(-1);
        }
        EntryDialog entryDialog = new EntryDialog(null);
        entryDialog.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        entryDialog.setVisible(true);
    }
}
